from django.http import HttpResponse
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework import serializers

from users.serializers import UserSerializer, MyTokenTokenObtainPairSerializer, UserDetailSerializer, \
    UpdatePasswordSerializer
from django.contrib.auth.models import User
from django.views import View
from rest_framework import viewsets
from utils.verifyUtil import VerifyUtil
import io

from djdemo32.settings import CACHES
from config.dbs.redisConfig import KEY_TEMPLATE,EXPIRE_TIME
from django_redis import get_redis_connection



# Create your views here.

# 验证码的视图
#  验证码不需要增删改查

class ImageVerifyView(View):

    # 127.0.0.1:8000/user/xxxx   ==> get
    def get(self,request,func,uuid):
        imgverifyUtil = VerifyUtil()  # 验证码的实例对象

        img,code = imgverifyUtil.verify_code()  #  img 图片数据   code  验证码数据
        #  生成验证码图片  但是生成的图片不需要永久存储
        #  只在请求的时候生成需要   所以需要字节流  生成临时文件
        img_bytes = io.BytesIO()  #  生成临时文件
        #  把图片存储在 img_bytes 字节文件里面  指定 png格式
        img.save(img_bytes,format='PNG')
        #  把png字节文件数据  读取返回出去
        img_bytes = img_bytes.getvalue()

        #   存储一份在redis 里面
        #  把redis连接信息 作为参数   传入进来 ==》 redis 缓存对象
        cache = get_redis_connection(alias='verify_codes')

        #  把验证码存入
        # set(key:value)    set()写入
        cache.set(KEY_TEMPLATE % (func,uuid),code,EXPIRE_TIME)

        #  返回响应到前端的时候  ==》  是字节数据
        return HttpResponse(img_bytes,content_type='image/png')


#  注册用户
#  需要有增删改查操作  所以用ModelViewSet


class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

#   重写 权限的分配   登录
    def get_permissions(self):
        if self.action in ["info","now"]:
            #  IsAuthenticated  检验是否登录
            permission_classes = [IsAuthenticated]
        else:
            permission_classes = []

        return [permission() for permission in permission_classes]

    #  重写序列化器的方法
    def get_serializer_class(self):
        if self.action == 'info':
            return UserDetailSerializer
        elif self.action == 'password':
            return UpdatePasswordSerializer
        else:
            return UserSerializer

    #  前端传入数据与 数据库 不匹配
    #  所以需要重写 create
    def create(self,request,*args,**kwargs):

        #  获取前端数据 json
#   进行反序列化
        serializer = self.get_serializer(data= request.data)  # 创建操作
        serializer.is_valid(raise_exception= True)

        #  获取用户名
        username = request.data.get('username')
        #  获取密码
        password = request.data.get('password')
        # 存储
        user = User(username=username)

        # 密码进行加密  set_password
        user.set_password(password)
        user.save()

        #  返回数据 json格式的数据
        return Response(serializer.data)

#  自定义 now 方法
    @action(methods=['get'],detail=False)   #不需要传ID  默认当前的登录用户
    def now(self,request):
        #  序列化
        serializer = self.get_serializer(request.user)
        return Response(serializer.data)


    @action(methods=['put'],detail=False)   #不需要传ID  默认当前的登录用户
    def info(self,request):

        #  获取用户数据
        user = request.user
        #  安全机制
        request.POST_mutable = True   #  允许修改post掺入的参数   本来传用户1  结果传成用户2
        #  所以就指定修改
        request.data["user"] = user.id

        #  一对一正反向查询
        if hasattr(user,"userdetail"):
            #  修改
            # 前端传入的数据  requests.data
            user_detail_serializer = self.get_serializer(instance=user.userdetail,data=request.data)
        else:
            #  创建
            user_detail_serializer = self.get_serializer(data=request.data)
        user_detail_serializer.is_valid(raise_exception=True)
        user_detail_serializer.save()
        return Response(user_detail_serializer.data)


    #  修改密码
    @action(methods=['put'],detail=False)
    def password(self,request):
# 获取当前的用户信息
        user = request.user
# 校验是否通过
# request.data
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

#  持久化保持
# 获取新密码
        password = serializer.data.get('password')
        print(password)
        new_password = serializer.data.get('new_password')
        #  进行加密
        user.set_password(new_password)
        user.save()
        return Response({"msg":"密码修改成功"})
        # return Response("密码修改成功")

#  数据的反序列化是用的   UserDetailSerializer

class MyTokenTokenObtainPairView(TokenObtainPairView):
    #  指定序列化器
    serializer_class = MyTokenTokenObtainPairSerializer












